AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )
include( 'shared.lua' )

	/*
		Stances
		
			I'm not sure if I'll have to use this but if I do...
		
		0 = idle
		
		1 = alert
		
		2 = combat
		
		3 = scared
		
		4 = dead
		
		
		
	*/
	
	schdIdle = ai_schedule.New( "AI Type idle" );
		
		schdIdle:AddTask( "Idle", 0 );
	
	schdMove = ai_schedule.New( "AI Type move" );
		
		schdMove:AddTask( "ResetSequence", 0 );
		schdMove:EngTask( "TASK_GET_PATH_TO_LASTPOSITION", 0 );
		schdMove:EngTask( "TASK_RUN_PATH", 0 );
		schdMove:AddTask( "CheckPos", 0 );
		schdMove:AddTask( "SetIdle", 0 );
		
	schdIdlePatrol = ai_schedule.New( "AI Type idlepatrol" );
		
		schdIdlePatrol:AddTask( "ResetSequence", 0 );
		schdIdlePatrol:EngTask( "TASK_GET_PATH_TO_RANDOM_NODE", 150 );
		schdIdlePatrol:EngTask( "TASK_WALK_PATH", 0 );
		schdIdlePatrol:EngTask( "TASK_WAIT_FOR_MOVEMENT", 0 );
		schdIdlePatrol:AddTask( "SetIdle", 0 );
		
	schdPatrol = ai_schedule.New( "AI Type combatpatrol" );
	
		schdPatrol:AddTask( "ResetSequence", 0 );
		schdPatrol:EngTask( "TASK_GET_PATH_TO_RANDOM_NODE", 150 );
		schdPatrol:EngTask( "TASK_WALK_PATH", 0 );
		-- Add a checker to look for enemy if so then schdfight
		schdPatrol:EngTask( "TASK_WAIT_FOR_MOVEMENT", 0 );
		
	schdFight = ai_schedule.New( "AI Type fight" );
		
		schdFight:AddTask( "ResetSequence", 0 );
		schdFight:AddTask( "CheckFight", 0 );
		schdFight:AddTask( "SetIdle", 0 );

function ENT:Initialize( ) --This function is run when the entity is created so it's a good place to setup our entity.

	local Mdl = {
		
		"models/humans/group01/male_02.mdl",
		"models/humans/group01/female_02.mdl"
		
		}
 
	self:SetModel( Mdl[math.random(1, #Mdl)] ); -- Sets the model of the NPC.
	
	Mdl = nil;
	
	self:SetHullType( HULL_HUMAN ); -- Sets the hull type, used for movement calculations amongst other things.
	self:SetHullSizeNormal( );
	
	self:SetNPCState( NPC_STATE_SCRIPT );
	self:SetSolid(  SOLID_BBOX ); -- This entity uses a solid bounding box for collisions.
	self:SetMoveType( MOVETYPE_STEP );
	
	self:CapabilitiesAdd( CAP_MOVE_GROUND | CAP_OPEN_DOORS | CAP_ANIMATEDFACE | CAP_TURN_HEAD | CAP_USE_SHOT_REGULATOR | CAP_AIM_GUN | CAP_AUTO_DOORS| CAP_OPEN_DOORS | CAP_MOVE_SHOOT ); -- Adds what the NPC is allowed to do ( It cannot move in this case ).
	
	self:SetUseType( SIMPLE_USE ); -- Makes the ENT.Use hook only get called once at every use.
	self:DropToFloor();
 
	self:SetMaxYawSpeed( 30 ); --Sets the angle by which an NPC can rotate at once.
	
	self:SetHealth(100);
 
end

function ENT:OnTakeDamage(dmginfo)

	self:SetHealth( self:Health() - dmginfo:GetDamage() );
	
	if self:Health() <= 0 then //run on death
	
		self:SetSchedule( SCHED_FALL_TO_GROUND ); //because it's given a new schedule, the old one will end.
		self:ClearNPC();
		self:SetVar("CrntTargets", nil);
		
		return;
		
	end
	
	
	local Targets = self:GetVar("CrntTargets");
	local Attacker = dmginfo:GetAttacker();
	
	local tab = {
	
		Attacker
	
	};

	if Targets then
	
		for _, v in pairs(Targets) do
			
			if IsValid(v) && v != Attacker then
			
				table.insert(tab, v);
				
			end
			
		end
		
	end
	
	PrintTable(tab);
	
	self:SetVar("CrntTargets", tab);	
	
end 

function ENT:Think()
	
end

function ENT:AcceptInput( Name, Activator, Caller )	
	
	local NPCGroup = CAKE.NPCTable[self:GetVar("BasicInfo").UID].Group;
	local PlyGroup = CAKE.GetCharField( Caller, "group" );

	if Name == "Use" && Caller:IsPlayer() && PlyGroup != NPCGroup then
	
		CAKE.NPCJoinGroup( self, PlyGroup);
		self:PlaySentence("METROPOLICE_BACK_UP_C", 0, 1);
	
	end
	
end
 
/*---------------------------------------------------------
   Name: SelectSchedule
---------------------------------------------------------*/
function ENT:SelectSchedule()
 
	self:StartSchedule( schdIdlePatrol ) //run the schedule we created earlier
 
end

/*---------------------------------------------------------
   Task: PlaySequence
---------------------------------------------------------*/
function ENT:TaskStart_PlaySequence( data )
 
	local SequenceID = data.ID
 
	if ( data.Name ) then SequenceID = self:LookupSequence( data.Name )	end
 
	self:ResetSequence( SequenceID )
	self:SetNPCState( NPC_STATE_SCRIPT )
 
	local Duration = self:SequenceDuration()
 
	if ( data.Speed && data.Speed > 0 ) then 
 
		SequenceID = self:SetPlaybackRate( data.Speed )
		Duration = Duration / data.Speed
 
	end
 
	self.TaskSequenceEnd = CurTime() + Duration
 
end
/*---------------------------------------------------------*/
function ENT:Task_PlaySequence( data )
 
	// Wait until sequence is finished
	if ( CurTime() < self.TaskSequenceEnd ) then return end
 
	self:TaskComplete()
	self:SetNPCState( NPC_STATE_NONE )
 
	// Clean up
	self.TaskSequenceEnd = nil
 
end

/*---------------------------------------------------------
   Task: Idle
---------------------------------------------------------*/
//Further Optimize and add more idling sequences.
function ENT:TaskStart_Idle( data )
 
	local SequenceID = self:LookupSequence( "LineIdle0"..tostring(math.random(1, 3)) );
	
	self:SetVar("Speaking", false);
 
	self:ResetSequence( SequenceID )
	self:SetNPCState( NPC_STATE_SCRIPT )
 
end
/*---------------------------------------------------------*/
//Further Optimize and add more idling sentences.

local function IdleSentence(self)

	local rand = math.random( 1, 31 );
	local ChosenSentence;
	local Gender;
	
	if string.find(self:GetModel(), "female") then Gender = "female"; else Gender = "male"; end
		
	if rand <= 9 then
	
		ChosenSentence = "vo/npc/"..Gender.."01/question0"..tostring(rand)..".wav";
	
	elseif rand >= 10 then
		
		if rand == 24 then rand = 25; end
		
		if Gender == "male" && rand == 31 then rand = 30; end
		
		ChosenSentence = "vo/npc/"..Gender.."01/question"..tostring(rand)..".wav";
		
	end
	
	return ChosenSentence;
	
end

function ENT:Task_Idle( data )
	
	if !self:GetVar("Speaking") then
	
		local ChosenSentence = IdleSentence(self);
		
		self:SetVar("SoundDuration", CurTime() + SoundDuration( ChosenSentence ) + math.random( 10, 35) );
		self:SetVar("Speaking", true);
		self:EmitSound( ChosenSentence, 65, 100 );
		WorldSound( ChosenSentence, self:GetPos(), 75, 100 )
	
	else
	
		if self:GetVar("SoundDuration") < CurTime() then 

			self:TaskComplete();
			self:SetVar("Speaking", nil);
			self:SetVar("SoundDuration", nil);
				
			if math.random(1, 2) == 1 then self:StartSchedule(schdIdlePatrol); end
		
		end
		
		return;
		
	end
 
end

/*---------------------------------------------------------
   Task: ResetSequence
---------------------------------------------------------*/

function ENT:TaskStart_ResetSequence( data )

	self:ResetSequence( "Idle" )
	self:SetNPCState( NPC_STATE_NONE )

end
/*---------------------------------------------------------*/
function ENT:Task_ResetSequence( data )
 
	self:TaskComplete()
 
end

/*---------------------------------------------------------
   Task: CheckPos
---------------------------------------------------------*/

function ENT:TaskStart_CheckPos( data )

	self.Checker = true;

end
/*---------------------------------------------------------*/
function ENT:Task_CheckPos( data )

	if self.Checker then self.Checker = nil; return; end

	if self:GetMovementActivity() == -1 then
 
		self:TaskComplete();
	
	end
	
	return;
 
end

/*---------------------------------------------------------
   Task: CheckFight
---------------------------------------------------------*/

function ENT:TaskStart_CheckFight( data )

end
/*---------------------------------------------------------*/
function ENT:Task_CheckFight( data )

	self:TaskComplete();
 
end

/*---------------------------------------------------------
   Task: CheckPos
---------------------------------------------------------*/

function ENT:TaskStart_SetIdle( data )

end
/*---------------------------------------------------------*/
function ENT:Task_SetIdle( data )
 
	self:TaskComplete();
		
	self:StartSchedule(schdIdle);
 
end

/*Mr. Hype | Kumandr: I need to add to the task check think func
Mr. Hype | Kumandr: to check for enemies
Mr. Hype | Kumandr: Then add a table of the enemies and randomly choose one to target
Mr. Hype | Kumandr: Then start a new schedule
Mr. Hype | Kumandr: Fight to take cover, fire if out of bullets cover again fire, if opponent dies pick another target or if the list is empty destroy it then continue move schedule or if that move is done then idle
Mr. Hype | Kumandr: SO SIMPLE

Not sure if I have to do it but maybe when fighting add a check for fighting to keep track of ammo and reload and take cover accordingly
*/